package com.yehun.shiro;

import com.yehun.entity.User;
import com.yehun.enums.StatusEnum;
import com.yehun.service.UserService;
import com.yehun.utils.MapperUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class UserRealm extends DefautAuthorizingRealm {

    private final static Logger logger = LoggerFactory.getLogger(UserRealm.class);

    @Autowired
    private UserService userService;

    @Override
    public void setName(String name) {
        super.setName(this.getClass().getName());
    }

    @Override
    public Class getAuthenticationTokenClass() {
        return UserToken.class;
    }

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        UserToken token = (UserToken) authcToken;
        logger.debug("验证当前Subject时获取到token为{}", ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
        User user = userService.getByEmail(token.getUsername());
        if (user == null) {
            throw new UnknownAccountException();
        }
        if (!Objects.equals(user.getPassword(), String.valueOf(token.getPassword()))) {
            throw new IncorrectCredentialsException();
        }
        if (user.getStatus() != StatusEnum.NORMAL) {
            throw new DisabledAccountException();
        }
        ShiroUser loginUser = MapperUtils.map(user, ShiroUser.class);
        return new SimpleAuthenticationInfo(loginUser, token.getPassword(), getName());
    }


    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //ShiroUser shiroUser = (ShiroUser) principals.fromRealm(getName()).iterator().next();
        ShiroUser shiroUser = (ShiroUser)principals.getPrimaryPrincipal();
        logger.info("shiroUser={}", shiroUser);
        User loginUser = userService.getByUserId(shiroUser.getUserId());
        //根据身份信息获取权限信息
        List<String> roles = new ArrayList<>();
        roles.add(loginUser.getType().toString().toLowerCase());
        switch (loginUser.getType()) {
            case ROOT:
                authorizationInfo.addRole(ShiroUserType.ADMIN.toString().toLowerCase());
                authorizationInfo.addRole(ShiroUserType.USER.toString().toLowerCase());
                break;
            case ADMIN:
                authorizationInfo.addRole(ShiroUserType.USER.toString().toLowerCase());
                break;
        }
        authorizationInfo.addRoles(roles);
        List<String> permissions = new ArrayList<>();
        authorizationInfo.addStringPermissions(permissions);
        authorizationInfo.addRoles(roles);
        return authorizationInfo;
    }

}
